home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / font3d10.zip / font3d.cpp < prev    next >
C/C++ Source or Header  |  1994-09-15  |  12KB  |  416 lines

  1. //=================================================================================================
  2. //   Font3D.CPP
  3. //-------------------------------------------------------------------------------------------------
  4. //
  5. //   Copyright (c) 1994 by Todd A. Prater
  6. //   All rights reserved.
  7. //
  8. //-------------------------------------------------------------------------------------------------
  9.  
  10. #include <iostream.h>
  11. #include <fstream.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "List.H"
  15. #include "Geometry.H"
  16. #include "TrueType.H"
  17. #include "Build.H"
  18.  
  19. #define FORMAT_POV  0
  20. #define FORMAT_RAW  1
  21.  
  22. #define PI 3.1415926536
  23.  
  24. #define NONE        0
  25. #define BEVELED     1
  26. #define SMOOTH      2
  27.  
  28. void OutputTriangle(ofstream& outputfile, int format, TRIANGLE& t)
  29. {
  30.  
  31.    switch(format)
  32.    {
  33.       case FORMAT_POV:
  34.  
  35.          outputfile<<"triangle{"
  36.                    <<"<"<<t.v1.x<<","<<t.v1.y<<","<<t.v1.z<<">,"
  37.                    <<"<"<<t.v2.x<<","<<t.v2.y<<","<<t.v2.z<<">,"
  38.                    <<"<"<<t.v3.x<<","<<t.v3.y<<","<<t.v3.z<<">}"<<endl;
  39.          break;
  40.  
  41.    }
  42.  
  43. }
  44.  
  45.  
  46. void PrintGreeting(void)
  47. {
  48.    cout<<"---------------------------------------"<<endl;
  49.    cout<<"Font3D                     Version 0.50"<<endl;
  50.    cout<<"Object Creation Utility                "<<endl;
  51.    cout<<"Written by Todd A. Prater              "<<endl;
  52.    cout<<"---------------------------------------"<<endl;
  53. }
  54.  
  55.  
  56. void PrintOptions(void)
  57. {
  58.    cout<<endl;
  59.    cout<<"  Command Line Switches:"<<endl;
  60.    cout<<endl;
  61.    cout<<"    /ifilename    TrueType Font File to use."<<endl;
  62.    cout<<"    /ofilename    Output File to be later included in a scene "<<endl;
  63.    cout<<"                  description file."<<endl;
  64.    cout<<"    /nstring      Name of the object to generate (POV formats only)."<<endl;
  65.    cout<<"    /cnnn         ASCII Character Code of the letter to generate"<<endl;
  66.    cout<<"    /rnnn         Curve resolution."<<endl;
  67.    cout<<"    /dfloat       Depth of the generated object."<<endl;
  68.    cout<<"    /fr           Output RAW triangles."<<endl;
  69.    cout<<"    /fs           Output POV smooth_triangles."<<endl;
  70.    cout<<"    /tnnn         Angle threshold for smooth triangle output."<<endl;
  71.    cout<<endl;
  72. }
  73.  
  74.  
  75.  
  76. void OutputGlyph(ofstream& outputfile,
  77.                  TTFont&   font,
  78.                  CHARPTR   objName,
  79.                  USHORT    code,
  80.                  USHORT    format,
  81.                  USHORT    resolution,
  82.                  double    frontDepth,
  83.                  double    backDepth,
  84.                  double    edgeShrinkFactor,
  85.                  double    faceShrinkFactor,
  86.                  DOUBLE    angleThreshold )
  87. {
  88.  
  89.    int j;
  90.    SHORT upem;
  91.    DOUBLE  xmin,ymin,xmax,ymax;
  92.    LIST<TRIANGLE>  faceTriList;
  93.    LIST<TRIANGLE>  edgeTriList;
  94.    LIST<TRIANGLE>  bevelTriList;
  95.  
  96.  
  97.    cout<<"Triangulating Face...";cout.flush();
  98.    TriangulateFace(font,font.CharacterMap(code),
  99.                    resolution,faceShrinkFactor,faceTriList);
  100.    cout<<"Done."<<endl;
  101.  
  102.    cout<<"Triangulating Edges...";cout.flush();
  103.  
  104.    TriangulateEdges(font,
  105.                     font.CharacterMap(code),
  106.                     resolution,
  107.                     frontDepth-edgeShrinkFactor,
  108.                     backDepth+edgeShrinkFactor,
  109.                     angleThreshold,
  110.                     edgeTriList);
  111.  
  112.    cout<<"Done."<<endl;
  113.  
  114. /*
  115.    if (effects==BEVELED)
  116.    {
  117.       cout<<"Triangulating Bevels...";cout.flush();
  118.       TriangulateBevels(font,code,
  119.                         resolution,
  120.                         frontDepth,backDepth,
  121.                         faceShrinkFactor,edgeShrinkFactor,
  122.                         bevelTriList);
  123.       cout<<"Done."<<endl;
  124.    }
  125. */ 
  126.  
  127.    cout<<"Writing Output...";cout.flush();
  128.  
  129.    if (format==POV_SMOOTH || format==POV_FLAT)
  130.    {
  131.      upem = font.UnitsPerEm();
  132.      xmin = (DOUBLE)font.GlyphXMin(font.CharacterMap(code))/(DOUBLE)upem;
  133.      ymin = (DOUBLE)font.GlyphYMin(font.CharacterMap(code))/(DOUBLE)upem;
  134.      xmax = (DOUBLE)font.GlyphXMax(font.CharacterMap(code))/(DOUBLE)upem;
  135.      ymax = (DOUBLE)font.GlyphYMax(font.CharacterMap(code))/(DOUBLE)upem;
  136.  
  137.      if (objName==NULL)
  138.      {
  139.          outputfile<<"#declare ALPHA_"<<code<<"_XMin  = "<<xmin<<endl;
  140.          outputfile<<"#declare ALPHA_"<<code<<"_YMin  = "<<ymin<<endl;
  141.          outputfile<<"#declare ALPHA_"<<code<<"_ZMin  = "<<backDepth<<endl;
  142.          outputfile<<"#declare ALPHA_"<<code<<"_XMax  = "<<xmax<<endl;
  143.          outputfile<<"#declare ALPHA_"<<code<<"_YMax  = "<<ymax<<endl;
  144.          outputfile<<"#declare ALPHA_"<<code<<"_ZMax  = "<<frontDepth<<endl;
  145.          outputfile<<endl;
  146.          outputfile<<"#declare ALPHA_"<<code<<"_Width = "<<(xmax-xmin)<<endl;
  147.          outputfile<<"#declare ALPHA_"<<code<<"_Height= "<<(ymax-ymin)<<endl;
  148.          outputfile<<"#declare ALPHA_"<<code<<"_Depth = "<<(frontDepth-backDepth)<<endl;
  149.          outputfile<<endl;
  150.          outputfile<<"#declare ALPHA_"<<code<<" ="<<endl;
  151.          outputfile<<"  union {"<<endl;
  152.      }
  153.      else
  154.      {
  155.          outputfile<<"#declare "<<objName<<"_XMin   = "<<xmin<<endl;
  156.          outputfile<<"#declare "<<objName<<"_YMin   = "<<ymin<<endl;
  157.          outputfile<<"#declare "<<objName<<"_ZMin   = "<<backDepth<<endl;
  158.          outputfile<<"#declare "<<objName<<"_XMax   = "<<xmax<<endl;
  159.          outputfile<<"#declare "<<objName<<"_YMax   = "<<ymax<<endl;
  160.          outputfile<<"#declare "<<objName<<"_ZMax   = "<<frontDepth<<endl;
  161.          outputfile<<endl;
  162.          outputfile<<"#declare "<<objName<<"_Width  = "<<(xmax-xmin)<<endl;
  163.          outputfile<<"#declare "<<objName<<"_Height = "<<(ymax-ymin)<<endl;
  164.          outputfile<<"#declare "<<objName<<"_Depth  = "<<(frontDepth-backDepth)<<endl;
  165.          outputfile<<endl;
  166.          outputfile<<"#declare "<<objName<<" = "<<endl;
  167.          outputfile<<"  union {"<<endl;
  168.      }
  169.    }
  170.  
  171.    faceTriList.gotoFirst();
  172.    for (j=0;j<faceTriList.Count();j++)
  173.    {
  174.       faceTriList.Current()->v1.z=frontDepth;
  175.       faceTriList.Current()->v2.z=frontDepth;
  176.       faceTriList.Current()->v3.z=frontDepth;
  177.  
  178.       outputfile<<"    ";
  179.  
  180.       if (format==RAW)
  181.          faceTriList.Current()->Output(outputfile,format);
  182.       else
  183.          faceTriList.Current()->Output(outputfile,POV_FLAT);
  184.  
  185.       outputfile<<endl;
  186.       faceTriList.gotoNext();
  187.    }
  188.  
  189.  
  190.    faceTriList.gotoFirst();
  191.    for (j=0;j<faceTriList.Count();j++)
  192.    {
  193.       faceTriList.Current()->v1.z=backDepth;
  194.       faceTriList.Current()->v2.z=backDepth;
  195.       faceTriList.Current()->v3.z=backDepth;
  196.       faceTriList.Current()->n1= -faceTriList.Current()->n1;
  197.       faceTriList.Current()->n2= -faceTriList.Current()->n2;
  198.       faceTriList.Current()->n3= -faceTriList.Current()->n3;
  199.  
  200.       outputfile<<"    ";
  201.  
  202.       if (format==RAW)
  203.          faceTriList.Current()->Output(outputfile,format);
  204.       else
  205.          faceTriList.Current()->Output(outputfile,POV_FLAT);
  206.  
  207.       outputfile<<endl;
  208.       faceTriList.gotoNext();
  209.    }
  210.  
  211.    faceTriList.Empty();
  212.  
  213.  
  214.    edgeTriList.gotoFirst();
  215.    for(j=0;j<edgeTriList.Count();j++)
  216.    {
  217.       outputfile<<"    ";
  218.  
  219.       edgeTriList.Current()->Output(outputfile,format);
  220.       outputfile<<endl;
  221.       edgeTriList.gotoNext();
  222.    }
  223.  
  224.    edgeTriList.Empty();
  225.  
  226. /*
  227.  
  228.    if (effects==BEVELED)
  229.    {
  230.       bevelTriList.gotoFirst();
  231.       for (j=0;j<bevelTriList.Count();j++)
  232.       {
  233.          outputfile<<"    ";
  234.          bevelTriList.Current()->Output(outputfile);
  235.          outputfile<<endl;
  236.          bevelTriList.gotoNext();
  237.       }
  238.       bevelTriList.Empty();
  239.    }
  240. */
  241.  
  242.    if (format==POV_SMOOTH || format==POV_FLAT)
  243.    {
  244.      outputfile<<"  }"<<endl;
  245.      outputfile<<endl;
  246.    }
  247.  
  248.    outputfile<<endl;
  249.  
  250.    cout<<"Done."<<endl;
  251.  
  252.  
  253. }
  254.  
  255.  
  256.  
  257.  
  258. int main(int argc, char* argv[])
  259. {
  260.    ULONG   code;
  261.    ULONG   i;
  262.    char    switchChar;
  263.    CHAR    fontFileName[255];
  264.    CHARPTR objName = NULL;
  265.    char    outputFileName[255];
  266.  
  267. //   CHAR*  fontFileName = new CHAR[255];
  268.  
  269.    double  frontDepth    = 0.1;
  270.    double  backDepth     = 0.0;
  271.    double  shrinkFactor  = 0.0;
  272.    ULONG   threshold     = 20;
  273.    double  angleThreshold = threshold*PI/180;
  274.    ULONG   resolution    = 3;
  275.    USHORT  format        = POV_FLAT;
  276.  
  277.    BOOLEAN resolutionSpecified=FALSE;
  278.    BOOLEAN codeSpecified = FALSE;
  279.    BOOLEAN objectNameSpecified = FALSE;
  280.    BOOLEAN fontFileSpecified = FALSE;
  281.    BOOLEAN outputFileSpecified = FALSE;
  282.    BOOLEAN depthSpecified = FALSE;
  283.    BOOLEAN angleThresholdSpecified = FALSE;
  284.  
  285.    if (argc==1)
  286.    {
  287.       cout<<endl<<"  ERROR:  Nothing to do."<<endl;
  288.       cout<<endl;
  289.       PrintOptions();
  290.       exit(1);
  291.    }
  292.  
  293.    for (i=1;i<argc;i++)
  294.    {
  295.  
  296.       if (strlen(argv[i])<3) continue;
  297.        
  298.       if (argv[i][0]!='/')
  299.       {
  300.          cout<<endl<<"  ERROR:  Illegal switch -- '"<<argv[i]<<"'"<<endl;
  301.          exit(1);
  302.       }
  303.  
  304.       switchChar = argv[i][1];
  305.  
  306.       switch (switchChar)
  307.       {
  308.          case 'f':   switch((CHAR)(argv[i][2]))
  309.                      {
  310.                         case 'r':  format=RAW;
  311.                                    break;
  312.                         case 's':  format=POV_SMOOTH;
  313.                                    break;
  314.                         default:   cout<<endl<<"  ERROR:  Illegal switch -- '/f"
  315.                                        <<((CHAR)(argv[i][2]))<<"'."<<endl;
  316.                                    break;    
  317.                      }
  318.                      break;
  319.          case 't':   sscanf(argv[i]+2,"%d",&threshold);
  320.                      angleThresholdSpecified=TRUE;
  321.                      break;
  322.          case 'r':   sscanf(argv[i]+2,"%d",&resolution);
  323.                      resolutionSpecified=TRUE;
  324.                      break;
  325.          case 'c':   sscanf(argv[i]+2,"%d",&code);
  326.                      codeSpecified=TRUE;
  327.                      break;
  328.          case 'n':   if (objectNameSpecified==FALSE)
  329.                         objName = new CHAR[255];
  330.                      strcpy((char*)objName,argv[i]+2);
  331.                      objectNameSpecified=TRUE;
  332.                      break;
  333.          case 'i':   strcpy((char*)fontFileName,argv[i]+2);
  334.                      fontFileSpecified=TRUE;
  335.                      break;
  336.          case 'o':   strcpy(outputFileName,argv[i]+2);
  337.                      outputFileSpecified=TRUE;
  338.                      break;
  339.          case 'd':   sscanf(argv[i]+2,"%5lf",&frontDepth);
  340.                      depthSpecified=TRUE;
  341.                      break;
  342.          default:    cout<<endl<<"  ERROR:  Illegal switch -- '"<<argv[i]<<"'"<<endl;
  343.                      exit(1);
  344.                      break;
  345.       }
  346.    }
  347.  
  348.  
  349.    if (fontFileSpecified==FALSE)
  350.    {
  351.       cout<<endl<<"  ERROR:  No font file specified."<<endl;
  352.       exit(1);
  353.    }
  354.  
  355.    if (outputFileSpecified==FALSE)
  356.    {
  357.       cout<<endl<<"  ERROR:  No output file specified."<<endl;
  358.       exit(1);
  359.    }
  360.  
  361.    if (codeSpecified==FALSE)
  362.    {
  363.       cout<<endl<<"  ERROR:  No character code specified."<<endl;
  364.       exit(1);
  365.    }
  366.  
  367.    if (angleThresholdSpecified==TRUE)
  368.    {
  369.       angleThreshold = threshold*PI/180;
  370.    }
  371.  
  372.  
  373.    TTFont UserFont(fontFileName);
  374.    ofstream outputfile(outputFileName);
  375.  
  376.    cout<<endl;
  377.    cout<<"Font:             "<<UserFont.FullName()<<endl;
  378.    cout<<"Curve Resolution: "<<resolution;
  379.    if (resolutionSpecified)
  380.       cout<<endl;
  381.    else
  382.       cout<<" (default)"<<endl;
  383. /*
  384.    if (effects==BEVELED)
  385.       cout<<"Shrink Factor:    "<<shrinkFactor<<endl;
  386. */
  387.  
  388.    cout<<"Character Code:   "<<code;
  389.    if (codeSpecified)
  390.       cout<<endl;
  391.    else
  392.       cout<<" (default)"<<endl;
  393.    cout<<"Character:        "<<(char)code<<endl;
  394.    cout<<"Depth:            "<<frontDepth;
  395.    if(depthSpecified)
  396.       cout<<endl;
  397.    else
  398.       cout<<" (default)"<<endl;
  399.    if (format == POV_SMOOTH)
  400.       cout<<"Generating Smooth Triangles."<<endl;
  401.    else if (format == RAW)
  402.       cout<<"Generating RAW Output."<<endl;
  403.  
  404.    cout<<"Output File:      "<<outputFileName<<endl;
  405.    cout<<"Angle Threshold:  "<<threshold<<" Degrees, "<<angleThreshold<<" Radians."<<endl;
  406.  
  407.    cout<<endl;
  408.  
  409.    OutputGlyph(outputfile, UserFont, objName, code, format, resolution, frontDepth, backDepth,
  410.                shrinkFactor,shrinkFactor,angleThreshold);
  411.  
  412.  
  413.    return 0;
  414. }
  415.  
  416.